#include <iostream>
#include <string>
#include <vector>

// FBReader 核心库头文件
#include <ZLApplication.h>
#include <ZLibrary.h>
#include <ZLFile.h>
#include <ZLInputStream.h>
#include <ZLEncodingConverter.h>
#include <ZLStringUtil.h>
#include <ZLUnicodeUtil.h>

// 测试工具函数
class TestRunner {
private:
    int passed;
    int failed;
    
public:
    TestRunner() : passed(0), failed(0) {}
    
    template<typename T>
    void assertEqual(const T& actual, const T& expected, const std::string& testName) {
        if (actual == expected) {
            std::cout << "✓ PASS: " << testName << std::endl;
            passed++;
        } else {
            std::cout << "✗ FAIL: " << testName << std::endl;
            std::cout << "  Expected: " << expected << std::endl;
            std::cout << "  Actual: " << actual << std::endl;
            failed++;
        }
    }
    
    void assertTrue(bool condition, const std::string& testName) {
        if (condition) {
            std::cout << "✓ PASS: " << testName << std::endl;
            passed++;
        } else {
            std::cout << "✗ FAIL: " << testName << std::endl;
            failed++;
        }
    }
    
    void printSummary() {
        std::cout << "\n=== Test Summary ===" << std::endl;
        std::cout << "Passed: " << passed << std::endl;
        std::cout << "Failed: " << failed << std::endl;
        std::cout << "Total: " << (passed + failed) << std::endl;
        
        if (failed == 0) {
            std::cout << "🎉 All tests passed!" << std::endl;
        } else {
            std::cout << "❌ Some tests failed!" << std::endl;
        }
    }
};

// 测试 ZLStringUtil 功能
void testStringUtil(TestRunner& runner) {
    std::cout << "\n=== Testing ZLStringUtil ===" << std::endl;
    
    // 测试字符串分割
    std::vector<std::string> parts;
    ZLStringUtil::splitString("hello,world,test", ",", parts);
    runner.assertEqual(parts.size(), (size_t)3, "String split count");
    if (parts.size() >= 3) {
        runner.assertEqual(parts[0], std::string("hello"), "First part");
        runner.assertEqual(parts[1], std::string("world"), "Second part");
        runner.assertEqual(parts[2], std::string("test"), "Third part");
    }
    
    // 测试字符串修剪
    std::string testStr = "  hello world  ";
    ZLStringUtil::stripWhiteSpaces(testStr);
    runner.assertEqual(testStr, std::string("hello world"), "Strip whitespaces");
    
    // 测试字符串连接
    std::vector<std::string> joinParts = {"a", "b", "c"};
    std::string joined = ZLStringUtil::join(joinParts, "-");
    runner.assertEqual(joined, std::string("a-b-c"), "String join");
}

// 测试 ZLUnicodeUtil 功能
void testUnicodeUtil(TestRunner& runner) {
    std::cout << "\n=== Testing ZLUnicodeUtil ===" << std::endl;
    
    // 测试 UTF-8 长度计算
    std::string utf8Str = "Hello 世界";
    int length = ZLUnicodeUtil::utf8Length(utf8Str);
    runner.assertTrue(length > 0, "UTF-8 length calculation");
    
    // 测试字符迭代
    std::vector<ZLUnicodeUtil::Ucs4Char> chars;
    ZLUnicodeUtil::utf8ToUcs4(chars, utf8Str);
    runner.assertTrue(chars.size() > 0, "UTF-8 to UCS4 conversion");
}

// 测试 ZLFile 功能
void testFileOperations(TestRunner& runner) {
    std::cout << "\n=== Testing ZLFile Operations ===" << std::endl;
    
    // 测试文件路径操作
    ZLFile testFile("/path/to/test.txt");
    runner.assertEqual(testFile.path(), std::string("/path/to/test.txt"), "File path");
    runner.assertEqual(testFile.name(), std::string("test.txt"), "File name");
    
    // 测试文件存在性检查（这里只是测试接口，不依赖实际文件）
    runner.assertTrue(true, "File operation interfaces");
}

// 测试编码转换功能
void testEncodingConversion(TestRunner& runner) {
    std::cout << "\n=== Testing Encoding Conversion ===" << std::endl;
    
    // 测试编码转换器可用性
    shared_ptr<ZLEncodingConverter> converter = 
        ZLEncodingConverter::createConverter("UTF-8");
    runner.assertTrue(!converter.isNull(), "UTF-8 converter creation");
    
    if (!converter.isNull()) {
        runner.assertTrue(converter->isValid(), "UTF-8 converter validity");
    }
}

// 测试 ZLibrary 初始化
void testLibraryInitialization(TestRunner& runner) {
    std::cout << "\n=== Testing Library Initialization ===" << std::endl;
    
    // 测试库版本信息
    std::string version = ZLibrary::version();
    runner.assertTrue(!version.empty(), "Library version check");
    
    // 测试库初始化
    bool initSuccess = ZLibrary::init();
    runner.assertTrue(initSuccess, "Library initialization");
    
    if (initSuccess) {
        // 测试应用路径设置
        ZLibrary::setApplicationName("FBReaderAPITest");
        runner.assertTrue(true, "Application name setting");
        
        // 清理库
        ZLibrary::shutdown();
        runner.assertTrue(true, "Library shutdown");
    }
}

// 测试流操作
void testStreamOperations(TestRunner& runner) {
    std::cout << "\n=== Testing Stream Operations ===" << std::endl;
    
    // 测试内存流创建
    std::string testData = "Hello, FBReader API Test!";
    shared_ptr<ZLInputStream> stream = 
        ZLInputStream::create(testData.data(), testData.size());
    
    runner.assertTrue(!stream.isNull(), "Memory stream creation");
    
    if (!stream.isNull()) {
        runner.assertTrue(stream->open(), "Stream open");
        
        // 测试读取操作
        char buffer[100];
        int bytesRead = stream->read(buffer, sizeof(buffer));
        runner.assertTrue(bytesRead > 0, "Stream read");
        
        stream->close();
        runner.assertTrue(true, "Stream close");
    }
}

// 主测试函数
int main() {
    std::cout << "=========================================" << std::endl;
    std::cout << "FBReader Core Library API Test Suite" << std::endl;
    std::cout << "OpenHarmony Version" << std::endl;
    std::cout << "=========================================" << std::endl;
    
    TestRunner runner;
    
    try {
        // 运行各个模块的测试
        testLibraryInitialization(runner);
        testStringUtil(runner);
        testUnicodeUtil(runner);
        testFileOperations(runner);
        testEncodingConversion(runner);
        testStreamOperations(runner);
        
        // 打印测试总结
        runner.printSummary();
        
        return runner.failed > 0 ? 1 : 0;
        
    } catch (const std::exception& e) {
        std::cerr << "❌ Exception occurred: " << e.what() << std::endl;
        return 1;
    } catch (...) {
        std::cerr << "❌ Unknown exception occurred" << std::endl;
        return 1;
    }
}
